#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_FILE_SIZE 1024 * 1024 // 假设最大文件大小为1MB

// 解析HTTP请求行，获取请求方法、路径和版本信息
void parse_request_line(char *request_line, char *method, char *path, char *version) {
    sscanf(request_line, "%s %s %s", method, path, version);

    std::cout << std::string(method) << std::endl;
    std::cout << std::string(path) << std::endl;
    std::cout << std::string(version) << std::endl;
}

// 发送HTTP响应头和相应内容
void send_http_response(int client_socket, int status_code, const char *content_type, const char *content, int content_length) {
    char http_response_header[BUFFER_SIZE];
    if (status_code == 200) {
        sprintf(http_response_header, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n", content_type, content_length);
    } else if (status_code == 404) {
        sprintf(http_response_header, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 0\r\n\r\n");
    }

    write(client_socket, http_response_header, strlen(http_response_header));
    if (status_code == 200) {
        write(client_socket, content, content_length);
    }
}

// 处理客户端连接
void handle_client_connection(int client_socket) {
    char request_buffer[BUFFER_SIZE];
    char method[10];
    char path[BUFFER_SIZE];
    char version[10];

    // 读取客户端请求数据
    memset(request_buffer, 0, BUFFER_SIZE);
    read(client_socket, request_buffer, BUFFER_SIZE - 1);

    // 解析请求行
    char *request_line = strtok(request_buffer, "\r\n");
    parse_request_line(request_line, method, path, version);

    // 处理GET请求，尝试获取对应文件内容
    if (strcmp(method, "GET") == 0) {
        char full_path[BUFFER_SIZE];
        //sprintf(full_path, "./%s", path);
        if (path[strlen(path) - 1] == '/') {
            //sprintf(full_path, "%sindex.html", full_path);
        }
        std::string str  = "/home/wjiang/webserver-master/server/index.html";
        int file_fd = open(str.c_str(), O_RDONLY);
        if (file_fd!= -1) {
            struct stat file_stat;
            fstat(file_fd, &file_stat);
            int file_size = file_stat.st_size;
            if (file_size > MAX_FILE_SIZE) {
                send_http_response(client_socket, 500, "text/plain", "File too large", strlen("File too large"));
            } else {
                char file_content[MAX_FILE_SIZE];
                read(file_fd, file_content, file_size);
                send_http_response(client_socket, 200, "text/html", file_content, file_size);
                std::cout << "aaaaaaaaaaa" << std::endl;
            }
            close(file_fd);
        } else {
            send_http_response(client_socket, 404, "text/html", "", 0);
        }
    } else {
        send_http_response(client_socket, 501, "text/plain", "Method not implemented", strlen("Method not implemented"));
    }

    close(client_socket);
}

int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);

    // 创建套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 配置服务器地址结构体
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    // 绑定套接字到指定端口
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("Bind failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    // 监听端口，等待客户端连接
    if (listen(server_socket, 5) == -1) {
        perror("Listen failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", PORT);

    while (1) {
        // 接受客户端连接
        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_socket == -1) {
            perror("Accept failed");
            continue;
        }
    // 打印客户端的地址信息
       char ip[24] = {0};
       printf("客户端的IP地址: %s, 端口: %d\n",
       inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ip, sizeof(ip)),
       ntohs(client_addr.sin_port));

        // 处理客户端连接
        handle_client_connection(client_socket);
    }

    // 关闭服务器套接字（实际一般不会执行到这里，因为是循环等待连接）
    close(server_socket);
    return 0;
}
